var defaultOpts = {
    control: 'hue',
    defaultValue: '#191933',
    record: 6,
    mouseleaveHide:false,
    recodrOnHide: true,
    onChange: undefined,
    onStartFn: null,
    onEndFn: null,
    onHideFn: null,
    buttons: ['transparent', "#ffffff",
        "#000000", "#5C5C5C", "#7B7B7B", "#C4C4C4",
        "#CC0000", "#DB5050", "#E99899", "#FFC8B8",
        "#FFB700", "#F7C946", "#F7DB8B", "#FFF2CC",
        "#558303", "#89C915", "#ACDB7E", "#D9EAD3",
        "#0079E3", "#36A0FA", "#81D3E5", "#DFF8FF",
        "#0324B7", "#1F48FA", "#8B95FA", "#E3E5FC",
        "#9803C9", "#CE43FA", "#DE81FA", "#F2D6FA",
        "#0AD8DB", "#3EDB0A", "#DB0AD6", "#EAB905", "#FFEA00", "#0034FF"
    ]
};
function keepWithin(value, min, max) {
    if (value < min) {
        value = min;
    }
    if (value > max) {
        value = max;
    }
    return value;
}

function parseHex(string, expand) {
    string = string.replace(/[^A-F0-9]/ig, '');
    if (string === undefined || string === "") {
        return "";
    }
    var len = string.length;
    var diff = 6 - len,
        lastChar;
    if (diff) {
        lastChar = string[len - 1];
    }
    while (diff > 0) {
        string += lastChar;
        diff--;
    }
    return '#' + string;
}
function convertCase(string, letterCase) {
    return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase();
}
function getCoords(picker, container) {
    let pos = $B.DomUtils.position(picker);
    return { x: pos.left, y: pos.top };
}
function getElE(ins) {
    var minicolors = ins.elObj;
    if (!ins.ctlMap) {
        ins.ctlMap = {};
        ins.ctlMap["grid"] = $B.DomUtils.findByClass(minicolors, '.k_minicolors_grid')[0];
        ins.ctlMap["slider"] = $B.DomUtils.findByClass(minicolors, '.k_minicolors_slider')[0];
        ins.ctlMap["opacitySlider"] = $B.DomUtils.findByClass(minicolors, '.k_minicolors_opacity_slider')[0];
        ins.ctlMap["gridPicker"] = $B.DomUtils.findByClass(ins.ctlMap["grid"], '.k_minicolors_picker')[0];
        ins.ctlMap["sliderPicker"] = $B.DomUtils.findByClass(ins.ctlMap["slider"], '.k_minicolors_picker')[0];
        ins.ctlMap["opacityPicker"] = $B.DomUtils.findByClass(ins.ctlMap["opacitySlider"], '.k_minicolors_picker')[0];
        ins.ctlMap["gWidth"] = $B.DomUtils.outerWidth(ins.ctlMap["grid"]);
        ins.ctlMap["gHeight"] = $B.DomUtils.outerHeight(ins.ctlMap["grid"]);
        ins.ctlMap["sWidth"] = $B.DomUtils.outerHeight(ins.ctlMap["slider"]);
        ins.ctlMap["sHeight"] = $B.DomUtils.outerHeight(ins.ctlMap["slider"]);
        ins.ctlMap["$inners"] = $B.DomUtils.findByClass(ins.ctlMap["grid"], ".k_minicolors_grid_inner")[0];
    }
    return ins.ctlMap;
}
/***
 * css =  {hex:,opacity:}
 * **/
function updateFromInput(css) {
    var ctlMap = getElE(this);
    var hex = css["hex"],
        hsb, els,
        opacity = css["opacity"],
        x, y, r, phi,
        settings = this.opts,
        minicolors = this.elObj,
        // swatch = ctlMap.swatch,
        grid = ctlMap.grid,
        slider = ctlMap.slider,
        gridPicker = ctlMap.gridPicker,
        sliderPicker = ctlMap.sliderPicker,
        opacityPicker = ctlMap.opacityPicker;
    if (!hex) {
        hex = convertCase(parseHex(settings.defaultValue, true), "lowercase");
    }
    hsb = $B.hex2Hsb(hex);

    var _pos, bkColor,
        gH = ctlMap.gHeight,
        gW = ctlMap.gWidth,
        sH = ctlMap.sHeight - 4,
        sW = ctlMap.sWidth;
    switch (settings.control) {
        case 'wheel':
            r = keepWithin(Math.ceil(hsb.s * 0.75), 0, gH / 2);
            phi = hsb.h * Math.PI / 180;
            x = keepWithin(75 - Math.cos(phi) * r, 0, gW);
            y = keepWithin(75 - Math.sin(phi) * r, 0, gH);
            _pos = {
                top: y + 'px',
                left: x + 'px'
            };
            y = 150 - (hsb.b / (100 / gH));
            if (hex === '') {
                y = 0;
            }
            sliderPicker.style.top = y + 'px';
            bkColor = $B.hsb2Hex({
                h: hsb.h,
                s: hsb.s,
                b: 100
            });
            $B.DomUtils.css(slider, { "background-color": bkColor });
            break;

        case 'saturation':
            x = keepWithin((5 * hsb.h) / 12, 0, 150);
            y = keepWithin(gH - Math.ceil(hsb.b / (100 / gH)), 0, gH);
            _pos = {
                top: y + 'px',
                left: x + 'px'
            };
            y = keepWithin(sH - (hsb.s * (sH / 100)), 0, sH);
            sliderPicker.style.top = y + 'px';
            bkColor = $B.hsb2Hex({
                h: hsb.h,
                s: 100,
                b: hsb.b
            });
            $B.DomUtils.css(slider, { "background-color": bkColor });
            els = $B.DomUtils.find(minicolors, '.minicolors-grid-inner');
            $B.DomUtils.css(els, { 'opacity': hsb.s / 100 });
            break;

        case 'brightness':
            x = keepWithin((5 * hsb.h) / 12, 0, 150);
            y = keepWithin(gH - Math.ceil(hsb.s / (100 / gH)), 0, gH);
            _pos = {
                top: y + 'px',
                left: x + 'px'
            };
            y = keepWithin(sH - (hsb.b * (sH / 100)), 0, sH);
            sliderPicker.style.top = y + 'px';
            bkColor = $B.hsb2Hex({
                h: hsb.h,
                s: hsb.s,
                b: 100
            });
            els = $B.DomUtils.find(minicolors, '.minicolors-grid-inner');
            $B.DomUtils.css(els, { 'opacity': 1 - (hsb.b / 100) });
            break;
        default:
            x = keepWithin(Math.ceil(hsb.s / (100 / gW)), 0, gW);
            y = keepWithin(gH - Math.ceil(hsb.b / (100 / gH)), 0, gH);
            _pos = {
                top: y + 'px',
                left: x + 'px'
            };
            y = keepWithin(sH - (hsb.h / (360 / sH)), 0, sH);
            sliderPicker.style.top = y + 'px';
            bkColor = $B.hsb2Hex({
                h: hsb.h,
                s: 100,
                b: 100
            });
            $B.DomUtils.css(grid, { "background-color": bkColor });
            y = sH * (1 - opacity);
            opacityPicker.style.top = y + "px";
            break;
    }
    gridPicker.style.top = _pos.top;
    gridPicker.style.left = _pos.left;
}

function updateControl(target) {
    var ctlMap = getElE(this);
    var hue, saturation, brightness, x, y, r, phi,
        hex,
        opacity = 1,
        settings = this.opts,
        grid = ctlMap.grid,
        slider = ctlMap.slider,
        opacitySlider = ctlMap.opacitySlider,
        gridPicker = ctlMap.gridPicker,
        sliderPicker = ctlMap.sliderPicker,
        opacityPicker = ctlMap.opacityPicker;

    var gridPos = getCoords(gridPicker, grid),
        sliderPos = getCoords(sliderPicker, slider),
        opacityPos = getCoords(opacityPicker, opacitySlider);
    let go = $B.DomUtils.hasClass(target, "k_minicolors_grid")
        || $B.DomUtils.hasClass(target, "k_minicolors_slider")
        || $B.DomUtils.hasClass(target, "k_minicolors_opacity_slider");
    if (go) {
        let bkColor;
        let gWidth = ctlMap.gWidth;
        let gHeight = ctlMap.gHeight;
        let sHeight = ctlMap.sHeight;
        let $inners = ctlMap["$inners"];
        switch (settings.control) {
            case 'wheel':
                x = (gWidth / 2) - gridPos.x;
                y = (gHeight / 2) - gridPos.y;
                r = Math.sqrt(x * x + y * y);
                phi = Math.atan2(y, x);
                if (phi < 0) {
                    phi += Math.PI * 2;
                }
                if (r > 75) {
                    r = 75;
                    gridPos.x = 69 - (75 * Math.cos(phi));
                    gridPos.y = 69 - (75 * Math.sin(phi));
                }
                saturation = keepWithin(r / 0.75, 0, 100);
                hue = keepWithin(phi * 180 / Math.PI, 0, 360);
                brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / sHeight)), 0, 100);
                hex = $B.hsb2Hex({
                    h: hue,
                    s: saturation,
                    b: brightness
                });
                bkColor = $B.hsb2Hex({
                    h: hue,
                    s: saturation,
                    b: 100
                });
                $B.DomUtils.css(slider, { "backgorund-color": bkColor });
                break;
            case 'saturation':
                hue = keepWithin(parseInt(gridPos.x * (360 / gWidth), 10), 0, 360);
                saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / sHeight)), 0, 100);
                brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / gHeight)), 0, 100);
                hex = $B.hsb2Hex({
                    h: hue,
                    s: saturation,
                    b: brightness
                });
                bkColor = $B.hsb2Hex({
                    h: hue,
                    s: 100,
                    b: brightness
                });
                slider.style.backgroundColor = bkColor;
                $B.DomUtils.css($inners, { "opacity": saturation / 100 });
                break;
            case 'brightness':
                hue = keepWithin(parseInt(gridPos.x * (360 / gWidth), 10), 0, 360);
                saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / gHeight)), 0, 100);
                brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / sHeight)), 0, 100);
                hex = $B.hsb2Hex({
                    h: hue,
                    s: saturation,
                    b: brightness
                });
                bkColor = $B.hsb2Hex({
                    h: hue,
                    s: saturation,
                    b: 100
                });
                slider.style.backgroundColor = bkColor;
                $B.DomUtils.css($inners, { "opacity": 1 - (brightness / 100) });
                //minicolors.find('.k_minicolors_grid_inner').css('opacity', 1 - (brightness / 100));
                break;
            default:
                hue = keepWithin(360 - parseInt(sliderPos.y * (360 / sHeight), 10), 0, 360);
                saturation = keepWithin(Math.floor(gridPos.x * (100 / gWidth)), 0, 100);
                brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / gHeight)), 0, 100);
                hex = $B.hsb2Hex({
                    h: hue,
                    s: saturation,
                    b: brightness
                });
                bkColor = $B.hsb2Hex({
                    h: hue,
                    s: 100,
                    b: 100
                });
                grid.style.backgroundColor = bkColor;
                break;
        }
        opacity = parseFloat(1 - (opacityPos.y / sHeight)).toFixed(2);
        doChange.call(this, hex, opacity);
        this._callChange();
    }
}
function doChange(hex, opacity) {
    if (hex.indexOf("rgb") > -1) {
        hex = $B.rgb2Hex(hex);
    }
    if (typeof opacity !== "undefined") {
        opacity = parseFloat(opacity);
    }
    if (opacity === NaN) {
        opacity = 1.0;
    }
    var lastChange = this['minicolors-lastChange'];
    if (!lastChange || lastChange.hex !== hex || lastChange.opacity !== opacity) {
        this['minicolors-lastChange'] = {
            hex: hex,
            opacity: opacity
        };
        this._updateInputs();
        if (!this.opts.recodrOnHide) {
            this.saveHisColor();
        }
    }
}
function move(moveEl, e) {
    var event = e._e;
    if (!this.target) {
        console.log("not target color skip");
        return;
    }
    let ofs = $B.DomUtils.offset(moveEl);
    var _this = this,
        picker = $B.DomUtils.findByClass(moveEl, "k_minicolors_picker")[0],
        offsetX = ofs.left,
        offsetY = ofs.top,
        x = Math.round(event.pageX - offsetX),
        y = Math.round(event.pageY - offsetY),
        wx, wy, r, phi;

    if (event.changedTouches) {
        x = event.changedTouches[0].pageX - offsetX;
        y = event.changedTouches[0].pageY - offsetY;
    }
    if (x < 0) {
        x = 0;
    }
    if (y < 0) {
        y = 0;
    }
    let tWidth = $B.DomUtils.width(moveEl);
    let tHeight = $B.DomUtils.height(moveEl);
    if (x > tWidth) {
        x = tWidth;
    }
    if (y > tHeight) {
        y = tHeight;
    }
    let go1 = $B.DomUtils.hasClass(moveEl.parentNode, '.k_minicolors_slider_wheel');
    let go2 = $B.DomUtils.hasClass(picker.parentNode, '.k_minicolors_grid');
    if (go1 && go2) {
        wx = 75 - x;
        wy = 75 - y;
        r = Math.sqrt(wx * wx + wy * wy);
        phi = Math.atan2(wy, wx);
        if (phi < 0) {
            phi += Math.PI * 2;
        }
        if (r > 75) {
            r = 75;
            x = 75 - (75 * Math.cos(phi));
            y = 75 - (75 * Math.sin(phi));
        }
        x = Math.round(x);
        y = Math.round(y);
    }
    if ($B.DomUtils.hasClass(moveEl, '.k_minicolors_grid')) {
        picker.style.top = y + 'px';
        picker.style.left = x + 'px';
        updateControl.call(_this, moveEl);
    } else {
        picker.style.top = y + 'px';
        updateControl.call(_this, moveEl);
    }
    return false;
}

class Color extends $B.BaseControl {
    constructor(tgObj, opts) {
        super();
        this.opts = $B.extendObjectFn(true, {}, defaultOpts, opts);
        this.$doc = opts.document ? opts.document : document;
        this.lastColors = [];//最近使用的颜色
        this.colorCookieName = "colorpr_";
        this.namespace = "kcolor" + $B.getIdIdx();
        var seft = this;
        this['minicolors-lastChange'] = {
            "hex": this.opts.defaultValue,
            "opacity": 1
        };
        this.$actor = $B.DomUtils.createEl("<div style='height: 8px;width:100%;top:-10px;padding-left:2px;border-bottom:2px solid #39393E;position:absolute;left:0px;'><i style='font-size:16px;color:#39393E;line-height:12px;position:relative;top:-5px' class='fa fa-up-dir'></i></div>");
        this.elObj = $B.DomUtils.createEl('<div tabindex="0" class="k_minicolors k_box_shadow k_minicolors_theme_default k_box_size" style="display:none;"/>');
        super.setElObj(this.elObj);
        $B.DomUtils.append(this.elObj,
            '<div tabindex="0" class="k_minicolors_panel  k_minicolors_slider_' + this.opts.control + '">' +
            '<div tabindex="0" class="k_minicolors_slider"><div class="k_minicolors_picker mv_picker"></div>' +
            '</div><div tabindex="0"  class="k_minicolors_opacity_slider"><div  tabindex="0"  class="k_minicolors_picker  mv_picker"></div>' +
            '</div><div  tabindex="0" class="k_minicolors_grid"><div  tabindex="0"  class="k_minicolors_grid_inner"></div>' +
            '<div tabindex="0" class="k_minicolors_picker  mv_picker"><div  tabindex="0" class="inner_mv_picker"></div></div></div></div>');
        $B.DomUtils.prepend(this.elObj, this.$actor);
        if (tgObj) {
            this.setTarget(tgObj);
        }
        this.isBodyClick = true;
        let $panel = $B.DomUtils.children(this.elObj, '.k_minicolors_panel')[0];
        var _this = this;       
        $B.DomUtils.mousedown($panel, (e) => {
            let evEl = e.target;
            let isFinded = false;
            while (evEl) {
                if ($B.DomUtils.hasClass(evEl, "k_minicolors_grid") || $B.DomUtils.hasClass(evEl, "k_minicolors_slider") || $B.DomUtils.hasClass(evEl, "k_minicolors_opacity_slider")) {
                    isFinded = true;
                    break;
                }
                evEl = evEl.parentNode;
            }
            if (isFinded) {
                $B.DomUtils.addListener(this.$doc, this.namespace + ".mousedown", (ev) => {
                    let tgEl = ev.target;
                    while (tgEl) {
                        if ($B.DomUtils.hasClass(tgEl, "k_minicolors_grid")
                            || $B.DomUtils.hasClass(tgEl, "k_minicolors_slider")
                            || $B.DomUtils.hasClass(tgEl, "k_minicolors_opacity_slider")) {
                            break;
                        }
                        tgEl = tgEl.parentNode;
                    }
                    _this.movingEl = tgEl;
                    _this.starting = true;
                });
                $B.DomUtils.addListener(this.$doc, this.namespace + ".mousemove", (ev) => {
                    if (_this.starting) {
                        _this.starting = false;
                        if (_this.opts.onStartFn) {
                            _this.opts.onStartFn();
                        }
                    }
                    let tgEl = _this.movingEl;
                    move.call(_this, tgEl, ev);
                });
                $B.DomUtils.addListener(this.$doc, this.namespace + ".mouseup", (ev) => {
                    if (!_this.starting) {
                        if (_this.opts.onEndFn) {
                            _this.opts.onEndFn();
                        }
                    }
                    _this.movingEl = undefined;
                    _this.starting = undefined;
                    $B.DomUtils.removeListener(ev.catpurer, this.namespace + ".*");
                });
            }
        });
        $B.DomUtils.mouseup($panel, (e) => {
            _this.movingEl = undefined;
            $B.DomUtils.removeListener(this.$doc, "k_color.*");
        });
        this.colorsBtnWrap = $B.DomUtils.createEl("<div  tabindex='0'  class='k_minicolors_color_buttons'></div>");
        $B.DomUtils.append(this.elObj, this.colorsBtnWrap);
        $B.DomUtils.click(this.colorsBtnWrap, (e) => {
            let el = e.target;
            while (el) {
                if ($B.DomUtils.hasClass(el, "k_color_btn")) {
                    break;
                }
                el = el.parentNode;
            }
            let color = $B.DomUtils.css(el, "background-color");
            seft.setValue(color);
            seft._callChange();
        });
        for (var i = 0, len = this.opts.buttons.length; i < len; ++i) {
            let $btn = $B.DomUtils.createEl("<div class='k_color_btn'  tabindex='0' style='background-color:" + this.opts.buttons[i] + "'></div>");
            $B.DomUtils.append(this.colorsBtnWrap, $btn);
            if (i === 0) {
                $B.DomUtils.addClass($btn, "k_mincolors_btn_nonecolor");
            }
        }       
        if (this.opts.mouseenter) {
            $B.DomUtils.mouseenter(this.elObj, this.opts.mouseenter);
        }
        this.rebuildFromCookie();
        $B.DomUtils.append(this.$doc.body, this.elObj);        
        //输入框
        let $inps = $B.DomUtils.createEl("<div tabindex='0' class='k_color_input_wap' style='width:100%;height:40px;'></div>");
        let $inpwap = $B.DomUtils.append(this.elObj, "<div tabindex='0' class='k_color_input_wap' style='width:100%;height:40px;position:absolute;left:0;bottom:0'></div>");
        let style = [];
        style.push("p{padding-left:1px;}p span{display:inline-block;width:32px;margin-left:2px;}");
        style.push("p span input{padding:0 !important;width:100%;height:18px;font-size:13px !important;line-height:18px;text-align:center;}");
        style.push(".k_label{text-align:center;height:18px;font-size:13px;line-height:18px;padding-top: 3px;}");
        $B.createTextIfr($inpwap,$inps,style);  
        
        $B.DomUtils.append($inps, "<p><span class='k_label' style='width:53px;'>Hex</span><span class='k_label'>R</span><span class='k_label'>G</span><span class='k_label'>B</span><span class='k_label'>A</span></p>");
        $B.DomUtils.append($inps, "<p><span style='width:53px;'><input spellcheck='false' id='k_color_hex' type='text'/></span><span><input id='k_color_r' type='text' /></span><span><input id='k_color_g' type='text' /></span><span><input id='k_color_b' type='text' /></span><span><input id='k_color_a' type='text' /></span></p>");
        
        this.$hex = $B.DomUtils.findbyId($inps, "k_color_hex");
        this.$r = $B.DomUtils.findbyId($inps, "k_color_r");
        this.$g = $B.DomUtils.findbyId($inps, "k_color_g");
        this.$b = $B.DomUtils.findbyId($inps, "k_color_b");
        this.$a = $B.DomUtils.findbyId($inps, "k_color_a");
     
        this._bindInputEvents($inps);
        updateFromInput.call(this, this['minicolors-lastChange']);
        this._updateInputs();
        $B.DomUtils.addListener(this.$doc, this.namespace + "g.click", (ev) => {
            if (!this._skiphide) {
                let e = ev.target;
                let helper = 8;
                let go2hide = true;
                if (e.nodeName !== "BODY") {
                    while (helper > 0 && e) {
                        if (e.nodeName === "BODY") {
                            break;
                        }
                        if ($B.DomUtils.hasClass(e, "k_minicolors") || $B.DomUtils.hasClass(e, "k_color_input_wap")) {
                            go2hide = false;
                            break;
                        }
                        e = e.parentNode;
                        helper--;
                    }
                }
                if (go2hide) {
                    this.hide();
                }
            }
        });
        if(this.opts.mouseleaveHide){
            $B.DomUtils.mouseleave(this.elObj,(e)=>{                
                this.hide();
            });
        }
    }
    rebuildFromCookie(){
        if(this.target){
            //从cookie恢复最近使用的5个颜色
            let ckey = this.colorCookieName +  this.target.id;
            var tmp = $B.getCookie(ckey);                   
            if (tmp !== "") {
                var colors = tmp.split(",");
                this.lastColors = colors;
                this._setLastColors();
            }
        }
    }
    _callChange() {
        if (this.opts.onChange) {
            let v = this['minicolors-lastChange'];
            this.opts.onChange.call(this.target, v.hex, v.opacity);
        }
    }
    _bindInputEvents(el) {
        if (!this.inputEvents) {
            this.inputEvents = {
                focus: (e) => {
                    console.log("focus", e.target);
                },
                input: (e) => {                   
                    clearTimeout(this.inputingTimer);
                    this.inputingTimer = setTimeout(() => {
                        let $in = e.target;
                        $B.DomUtils.removeClass(this.$hex, "k_input_value_err");
                        $B.DomUtils.removeClass(this.$r, "k_input_value_err");
                        $B.DomUtils.removeClass(this.$g, "k_input_value_err");
                        $B.DomUtils.removeClass(this.$b, "k_input_value_err");
                        $B.DomUtils.removeClass(this.$a, "k_input_value_err");
                        let r = parseInt(this.$r.value);
                        let g = parseInt(this.$g.value);
                        let b = parseInt(this.$b.value);
                        let a = parseFloat(this.$a.value);
                        let isErr = false;
                        if (r === NaN || r < 0 || r > 255) {
                            $B.DomUtils.addClass(this.$r, "k_input_value_err");
                            isErr = true;
                        }
                        if (g === NaN || g < 0 || g > 255) {
                            $B.DomUtils.addClass(this.$g, "k_input_value_err");
                            isErr = true;
                        }
                        if (b === NaN || b < 0 || b > 255) {
                            $B.DomUtils.addClass(this.$b, "k_input_value_err");
                            isErr = true;
                        }
                        if (a === NaN || a < 0 || a > 1) {
                            $B.DomUtils.addClass(this.$a, "k_input_value_err");
                            isErr = true;
                        }
                        if (!isErr) {
                            if ($in.id === "k_color_hex") {
                                if ($in.value.length === 6) {
                                    try {
                                        let v = "#" + $in.value;
                                        this.setValue(v, this['minicolors-lastChange'].opacity);
                                        this._callChange();
                                    } catch (x) {
                                        $B.DomUtils.addClass(this.$hex, "k_input_value_err");
                                        console.log(x);
                                    }
                                } else {
                                    $B.DomUtils.addClass(this.$hex, "k_input_value_err");
                                }
                            } else if ($in.id === "k_color_a") {
                                if ($in.value !== "") {
                                    this.setValue(this['minicolors-lastChange'].hex, $in.value);
                                    this._callChange();
                                }
                            } else {
                                try {
                                    let rgb = "rgb(" + r + "," + g + "," + b + ")";
                                    let hexVal = $B.rgb2Hex(rgb);
                                    this.setValue(hexVal, this['minicolors-lastChange'].opacity);
                                    this._callChange();
                                } catch (e1) {
                                    console.log(e1);
                                }
                            }
                        }
                    }, 500);
                }
            };
        }
        $B.DomUtils.bind(el, this.inputEvents);
    }
    _updateInputs() {
        var val = this['minicolors-lastChange'];
        this.$hex.value = val.hex.replace("#", "").toUpperCase();
        var rgbObj = $B.hex2RgbObj(val.hex);
        this.$r.value = rgbObj.r;
        this.$g.value = rgbObj.g;
        this.$b.value = rgbObj.b;
        this.$a.value = val.opacity;
    }
    setTarget(elObj) {
        if (typeof elObj === "string") {
            elObj = this.$doc.getElementById(elObj);
        }
        if (this.target && this.target !== elObj) {
            this._setLastColors();
            this.unbindTarget();            
        }
        this.target = elObj;
        this.rebuildFromCookie();
        if (!$B.DomUtils.hasClass(this.target, "k_color_picker_cls")) {
            $B.DomUtils.css(this.target, "background-image", "none");
            $B.DomUtils.addClass(this.target, "k_color_picker_cls");
            if(!$B.DomUtils.attribute(this.target,"unbindcolorev")){
                $B.DomUtils.addListener(this.target, this.namespace + ".click", (e) => {
                    if (this.elObj.style.display === "none") {
                        this.show();
                    } else {
                        this.hide();
                    }
                    return false;
                });
            }           
        }
        return this;
    }
    unbindTarget() {
        if (this.target) {
            $B.DomUtils.offEvents(this.target, this.namespace + ".click");
            $B.DomUtils.removeClass(this.target, "k_color_picker_cls");
            this.target = undefined;
        }
        return this;
    }
    setPosition(ofs) {
        let tH = $B.DomUtils.outerHeight(this.target) + 6;
        ofs.top = ofs.top + tH;
        let bodyW = $B.DomUtils.width(this.$doc.body);
        let bodyH = $B.DomUtils.height(this.$doc.body);
        if ((ofs.top + 250) > bodyH) {
            ofs.top = ofs.top - 250 - tH + 2;
            this.$actor.style.top = "231px";
            $B.DomUtils.css(this.$actor.firstChild, { top: "1px", transform: "rotateZ(180deg)" });
        } else {
            this.$actor.style.top = "-10px";
            $B.DomUtils.css(this.$actor.firstChild, { top: "-5px", transform: "rotateZ(0deg)" });
        }
        let w = ofs.left + 198;
        if (w > bodyW) {
            let diff = w - bodyW;
            ofs.left = ofs.left - diff;
            this.$actor.firstChild.style.left = diff + "px";
        } else {
            this.$actor.firstChild.style.left = "0px";
        }
        this.elObj.style.top = ofs.top + "px";
        this.elObj.style.left = ofs.left + "px";
        this.elObj.style.display = "block";
        return this;
    }    
    hide(isUnbind) {
        var _this = this;
        clearTimeout(this["hidetimer"]);
        if (isUnbind) {
            _this.unbindTarget();
        }
        if (_this.opts.onHideFn) {
            setTimeout(() => {
                _this.opts.onHideFn(_this);
            }, 1);
        }
        _this.elObj.style.display = "none";
        this._setLastColors();       
        return this;
    }
    saveHisColor() {
        clearTimeout(this.hisRecoderTimer);
        this.hisRecoderTimer = setTimeout(() => {
            this._setLastColors();
        }, 1500);
    }
    /**设置最近使用颜色**/
    _setLastColors() {
        var currentColor = this["minicolors-lastChange"].hex;
        this.lastColors.unshift(currentColor);
        this.lastColors = Array.from(new Set(this.lastColors));
        if (this.lastColors.length > this.opts.record) {
            this.lastColors = this.lastColors.slice(0 ,this.opts.record );
        }        
        var lastBtn = this.colorsBtnWrap.lastChild;
        for (let i = 0, len = this.lastColors.length; i < len; ++i) {
            $B.DomUtils.css(lastBtn, { "background-color": this.lastColors[i] });
            lastBtn = lastBtn.previousSibling;
        }
        var lastColorstr = this.lastColors.join(",");
        let ckey = this.colorCookieName ;
        if(this.target){
            ckey = ckey + this.target.id;
        }
        $B.writeCookie(ckey, lastColorstr, 3);
    }
    show(target,shift) {       
        if (this.target && target && this.target === target) {
            if(this.isShow()){
                return;
            }           
        }
        var _this = this;
        if (target) {
            _this.setTarget(target);
        }
        var ofs = $B.DomUtils.offset(_this.target);
        if(shift){
            if(shift.top){
                ofs.top = ofs.top + shift.top;
            }
            if(shift.left){
                ofs.left = ofs.left + shift.left;
            }
        }
        this._skiphide = true;
        _this.setPosition(ofs);
        setTimeout(() => {
            this._skiphide = undefined;
        }, 1);
        return this;
    }
    isShow() {
        var dis = $B.DomUtils.css(this.elObj, "display");
        return dis === "block";
    }
    setValue(value, opacity) {
        this._setLastColors();
        try {
            if (value.toLowerCase().indexOf("rgb") > -1) {
                value = $B.rgb2Hex(value);
            } else {
                $B.hex2RgbObj(value);
            }
            if (typeof opacity !== "undefined") {
                opacity = parseFloat(opacity);
            }
            if (opacity === undefined || opacity === NaN) {
                opacity = this['minicolors-lastChange'].opacity;
            }
        } catch (e) {
            console.log(e);
            return;
        }
        doChange.call(this, value, opacity);
        value = {
            "hex": value,
            "opacity": opacity
        };
        updateFromInput.call(this, value);
        return this;
    }
    getValue() {
        return this['minicolors-lastChange'];
    }
    destroy() {
        $B.DomUtils.offEvents(this.$doc, this.namespace + "g.click");
        this.$doc = undefined;
        this.unbindTarget();
        $B.DomUtils.remove(this.elObj);
        super.destroy();
    }
}
$B["Color"] = Color;